// 目标调整为：判断一个url host是否是游戏私服或色情网站
//
// # feature list:
//  a. 后缀是否是.com, .cn;
//  b. 后缀是否是.net, .org;
//  c. 后缀是否是.me, .en, .uk, .jp;
//  d. 是否包含baidu,sohu,sina,163,qq,snda,sdo等知名网站;
//  e. 是否在black list中(如：www.huxu.info, www.baisex.me);
//  f. 是否包含：sex, porn, cao, xx, jp, av, xingai, movie, sese等淫秽词;
//  g. 是否是数字英文串;
//  h. 是否在白名单中(如：www.7k7k.com, www.4399.com等)；
#include <vector>
#include <map>
#include <fstream>
#include <iostream>
#include "wumanber.h"
#include "line_stream_iterator.hpp"

using namespace std;

struct FeatureSet
{
	bool sufix_is_com_cn;//.com.cn
	bool sufix_is_net_org;//net, org, info
	bool sufix_is_me_en;//me,en,uk,jp
	bool is_brand_site;//baidu,sohu,sina,163,qq,snda,sdo
	bool is_click;//click, pop
	bool is_in_black_list;//baisex.me, huxu.info
	bool is_porn;//sex, porn, cao, xx, jp, av, xingai, movie, sese
	bool is_num_digit;
	bool is_in_white_list;
};

typedef std::map<std::string, int> Features;
bool is_ip_address(char* ip);

void split(const std::string& instr, std::vector<std::string>& result, const std::string& delim)
{
	std::string str(instr);
	size_t pos;
	while ((pos = str.find_first_of(delim)) != str.npos)
	{   
		if (pos > 0)
			result.push_back(str.substr(0, pos));
		str = str.substr(pos + 1); 
	}   
	if (str.length() > 0)
		result.push_back(str);
}

bool is_num_digit(const string& str)
{
	for (size_t i = 0; i < str.length(); ++i)
	{
		if (isdigit(str[i]))return true;
	}
	return false;
}

class FeatureExtractor
{
	public:
	FeatureExtractor(){}
	~FeatureExtractor()
	{
		for (map<string, WuManber*>::iterator it = wus.begin(); it != wus.end(); ++it)
			delete (it->second);
	}

	bool Init(const char* patterns)
	{
		ifstream pat(patterns);
		line_stream_iterator<> litr(pat);
		line_stream_iterator<> lend;
		for (; litr != lend; ++litr)
		{
			WuManber* tmp = new WuManber();
			vector<string> v;
			split(string(*litr), v, " ");
			tmp->Init(v);
			wus[v[0]] = (tmp);
		}
	}

	void extract(string& url, Features& fs)
	{
		for (map<string, WuManber*>::iterator it = wus.begin(); it != wus.end(); ++it)
		{
			fs[it->first] = (it->second)->Search(url);
		}

		fs["is_num_digit"] = is_num_digit(url);
		fs["is_ip_address"] = is_ip_address(const_cast<char* >(url.c_str()));
	}

	private:
	map<string, WuManber*> wus;
};

bool is_ip_address(char* st)
{
	int num, i, len;
	char *ch;
	//counting number of quads present in a given IP address
	int quadsCnt=0;
	len = strlen(st);
	if(len<7 || len>15) return false;
	ch = strtok(st, ".");
	while (ch != NULL) 
	{
		quadsCnt++;
		num = 0;
		i = 0;
		//  Get the current token and convert to an integer value
		while(ch[i]!='\0')
		{
			num = num*10;
			num = num+(ch[i]-'0');
			i++;
		}
		if(num<0 || num>255) return false;
		if( (quadsCnt == 1 && num == 0) || (quadsCnt == 4 && num == 0))	return false;
		ch = strtok(NULL, ".");
	}
	//  Check the address string, should be n.n.n.n format
	if(quadsCnt!=4)	return false;
	return true;
}

int main(int argc, char* argv[])
{
	if (argc != 2)
	{
		cout << "Usage: ./main patterns" << endl;
		return -1;
	}
	FeatureExtractor fector;
	fector.Init(argv[1]);
	string url;
	cout << "pls input url:" << endl;
	while (cin >> url)
	{
		Features fes;
		fector.extract(url, fes);
		for (Features::iterator it = fes.begin(); it != fes.end(); ++it)
			cout << it->first << ":" << it->second << " ";
		cout << "\npls input url:" << endl;
	}
	return 0;
}
